#include "GameEngine.h"
#include "Runtime/Engine/GameViewportClient.h"
#include "Runtime/CGI/DynamicCGI.h"
#include "Runtime/Engine/Application.h"
#include "Runtime/Engine/2D/Window.h"
#include "Runtime/Platform/Windows/WindowsApplication.h"
#include "Runtime/Platform/GenericWindow.h"
#include "Runtime/Thread/RenderingThreadContext.h"

namespace Alice
{
    void GameEngine::Init(IEngineLoop* inEngineLoop)
    {
        Engine::Init(inEngineLoop);
        mGameInstance=new GameInstance(this);
        mGameInstance->InitializeStandalone("Default");
        
        mGameViewportClient=new GameViewportClient;
        mGameViewportClient->Init(*(mGameInstance->mWorldContext),mGameInstance);
        mGameInstance->GetWorldContext()->mGameViewportClient=mGameViewportClient;

        mWindow=CreateGameWindow();
        CreateGameViewport(mGameViewportClient);
        mViewportWidget->mWindow=mWindow;
        SwitchGameWindowToUseGameViewport();
        //ENQUEUE_RENDER_COMMAND(Test)([](CGICommandList&inCGICommandList)
        //{
        //    Debug("test render command!");
        //});
    }
    void GameEngine::Tick(float inDeltaTime)
    {
        auto iterWorld=mWorldList.begin();
        const auto iterWorldEnd=mWorldList.end();
        while (iterWorld!=iterWorldEnd)
        {
            WorldContext*worldContext=*iterWorld;
            World*world=worldContext->mWorld;
            if(world!=nullptr)
            {
                world->Tick(0.0f);
            }
            iterWorld++;
        }
        RedrawViewports();
    }
    Window* GameEngine::CreateGameWindow()
    {
        Window* window=new Window;
        Application::Get()->AddWindow(window);
        window->ShowWindow();
        return window;
    }
    void GameEngine::CreateGameViewportWidget(GameViewportClient* inGameViewportClient)
    {
        mViewportWidget=new ViewportWidget;
    }
    void GameEngine::CreateGameViewport(GameViewportClient* inGameViewportClient)
    {
        CreateGameViewportWidget(inGameViewportClient);
        mSceneViewport=inGameViewportClient->CreateGameViewport(mViewportWidget);
        inGameViewportClient->mViewport=mSceneViewport;
        inGameViewportClient->SetViewportFrame(mSceneViewport);
    }
    void GameEngine::SwitchGameWindowToUseGameViewport()
    {
        mSceneViewport->ResizeFrame(0,0,EWindowMode::Windowed);
    }
    void GameEngine::RedrawViewports(bool bShouldPresent)
    {
        if(mGameViewportClient!=nullptr)
        {
            if(mGameViewportClient->mViewport!=nullptr)
            {
                mGameViewportClient->mViewport->Draw(bShouldPresent);
            }
        }
    }
}
